package base.keyboard
{
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.FocusEvent;
	import flash.events.KeyboardEvent;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.utils.Dictionary;
	
	import base.stages.StageReflection;
	
	/**
	 *键盘管理工厂 
	 * @author devin
	 */	
	public class KeyboardFactory extends EventDispatcher
	{
		/**
		 *舞台 
		 */		
		private var _stage:Stage;
		
		/**
		 *当前已按下键值列表 
		 */		
		private var _keyDownQueue:Array=[];
		
		/**是否响应按键事件*/
		private var _keyEvent:Boolean = true;
		private var _keyCombos:Dictionary=new Dictionary(false);
		/**
		 * 键盘管理工厂
		 */		
		public function KeyboardFactory()
		{
		}
		
		private static var _instance:KeyboardFactory;

		/**
		 *是否响应按键事件 
		 * @param value
		 */		
		public function set keyEvent(value:Boolean):void
		{
			_keyEvent = value;
		}

		public static function get Instance():KeyboardFactory
		{
			if(_instance == null)
			{
				_instance = new KeyboardFactory();
			}
			return _instance;
		}
		
		/**
		 *键盘管理工厂类注册  
		 * @param stage 舞台
		 * @param isCombos 是否开启组合键
		 * @param combosKeyIdle 组合键组成的间隔时间(毫秒)
		 */		
		public function register(stage:Stage):void
		{
			_stage=stage;			
			_stage.addEventListener(KeyboardEvent.KEY_DOWN, __onKeyDown, false, 0, true);
			_stage.addEventListener(KeyboardEvent.KEY_UP, __onKeyUp, false, 0, true);
			_stage.addEventListener(Event.DEACTIVATE, __onDeactivate, false, 0, true);
			StageReflection.stage.addEventListener(FocusEvent.FOCUS_IN,__onFocusChange);
			StageReflection.stage.addEventListener(FocusEvent.FOCUS_OUT,__onFocusChange);
		}
		
		private function __onFocusChange(evt:FocusEvent):void
		{
			if(StageReflection.stage.focus is TextField  && (StageReflection.stage.focus as TextField).type==TextFieldType.INPUT)
			{
				_keyEvent = false;
			}
			else
			{
				_keyEvent = true;
			}
		}
		
		/**
		 *增加一个类型的组合键
		 * @param type
		 */		
		public function addKeyCombo(type:String, idle:uint=0, isAction:Boolean=true):void
		{
			if(_keyCombos[type]!=null)return;
			var keyCombo:KeyCombo=new KeyCombo(type, idle, isAction);
			keyCombo.addEventListener(KeyEvent.COMBO_ACTION, __onKeyComboAction);
			keyCombo.addEventListener(KeyEvent.COMBO_ALL_KEY_DOWN, __onKeyComboAllKeyDown);
			keyCombo.addEventListener(KeyEvent.COMBO_ALL_KEY_DOWN_RELEASE, __onKeyComboAllKeyDownRelease);
			_keyCombos[type]=keyCombo;
		}
		
		/**
		 *移除一个类型的组合键
		 * @param type
		 */		
		public function removeKeyCombo(type:String):void
		{
			var keyCombo:KeyCombo=_keyCombos[type] as KeyCombo;
			if(keyCombo)
			{
				keyCombo.removeEventListener(KeyEvent.COMBO_ACTION, __onKeyComboAction);
				keyCombo.removeEventListener(KeyEvent.COMBO_ALL_KEY_DOWN, __onKeyComboAllKeyDown);
				keyCombo.removeEventListener(KeyEvent.COMBO_ALL_KEY_DOWN_RELEASE, __onKeyComboAllKeyDownRelease);
				keyCombo.dispose();
				keyCombo=null;
			}
			delete _keyCombos[type];
		}
		
		/**
		 *键盘按下 
		 * @param evt
		 */		
		private function __onKeyDown(evt:KeyboardEvent):void
		{
			if(!_keyEvent)return;
			addDownKey(evt.keyCode);
			dispatchEvent(new KeyEvent(KeyEvent.KEY_DOWN, evt.keyCode));
		}
		
		/**
		 *键盘松开 
		 * @param evt
		 */		
		private function __onKeyUp(evt:KeyboardEvent):void
		{
			removeDownKey(evt.keyCode);
			dispatchEvent(new KeyEvent(KeyEvent.KEY_UP, evt.keyCode));
		}
		
		/**
		 *失去焦点事件 
		 * @param evt
		 */
		private function __onDeactivate(evt:Event):void
		{
			dispatchEvent(new KeyEvent(KeyEvent.DEACTIVATE));
		}
		
		/**
		 *增加已按下的键值 
		 * @param code 键值
		 */
		private function addDownKey(code:uint):void
		{
			if(_keyDownQueue.indexOf(code, 0)==-1)
			{
				_keyDownQueue.push(code);
			}
		}
		
		/**
		 *删除已按下的键值 
		 * @param code 键值
		 */
		private function removeDownKey(code:uint):void
		{
			if(_keyDownQueue.indexOf(code, 0)>-1)
			{
				if(_keyDownQueue.indexOf(code, 0)!=-1)_keyDownQueue.splice(_keyDownQueue.indexOf(code, 0), 1);
			}
		}
		
		/**
		 *组合键监听创建
		 * @param type 名称类型
		 * @param keyCombos 要监听的组合键，数据格式：键值,键值,键值,...
		 * @param data 传输的数据
		 */	
		public function createCombosKey(type:String, name:String, keyCodes:Array, data:*=null):void
		{
			var keyCombo:KeyCombo=_keyCombos[type] as KeyCombo;
			if(keyCombo.keyComboExistByName(name))return;
			var keyComboCell:KeyComboCell=new KeyComboCell(type, name, keyCodes, data);
			keyCombo.addKeyCombo(keyComboCell);
		}
		
		/**
		 *组合键监听移除 
		 * @param type 类型
		 * @param name 名字
		 */	
		public function removeCombosKeyByName(type:String, name:String):void
		{
			var keyCombo:KeyCombo=_keyCombos[type] as KeyCombo;
			keyCombo.removeKeyComboByName(name);
		}
		
		/**
		 *当激活组合键时 
		 * @param evt
		 */		
		private function __onKeyComboAction(evt:KeyEvent):void
		{
			var keyComboCell:KeyComboCell=evt.data as KeyComboCell;
			dispatchEvent(new KeyEvent(KeyEvent.COMBO_ACTION, keyComboCell));
		}
		
		/**
		 *当释放组合键时 
		 * @param evt
		 */		
		private function __onKeyComboAllKeyDownRelease(evt:KeyEvent):void
		{
			var keyComboCell:KeyComboCell=evt.data as KeyComboCell;
			dispatchEvent(new KeyEvent(KeyEvent.COMBO_ALL_KEY_DOWN_RELEASE, keyComboCell));
		}
		
		/**
		 *当组合键全部键被按下时 
		 * @param evt
		 */
		private function __onKeyComboAllKeyDown(evt:KeyEvent):void
		{
			var keyComboCell:KeyComboCell=evt.data as KeyComboCell;
			dispatchEvent(new KeyEvent(KeyEvent.COMBO_ALL_KEY_DOWN, keyComboCell));
		}
		
		/**
		 *当前已按下键值列表 
		 */
		public function get keyDownQueue():Array
		{
			return _keyDownQueue;
		}
		
		/**
		 *指定的键值是否已按下 
		 * @param keyCode 键值
		 * @return 
		 */		
		public function isKeyDown(keyCode:uint):Boolean
		{
			return _keyDownQueue.indexOf(keyCode, 0)!=-1;
		}
		
		/**
		 *组合键 
		 */
		public function getKeyCombo(type:String):KeyCombo
		{
			return _keyCombos[type] as KeyCombo;
		}
		
		/**
		 *取消激活指定的组合键 
		 */		
		public function deactivateKeyCombo(type:String):void
		{
			var keyCombo:KeyCombo=getKeyCombo(type);
			if(keyCombo)keyCombo.isAction=false;
		}
		
//		/**
//		 *取消激活所有组合键 
//		 */		
//		public function deactivateAllKeyCombo():void
//		{
//			for each(var keyCombo:KeyCombo in _keyCombos)
//			{
//				keyCombo.isAction=false;
//			}
//		}
//		
//		/**
//		 * 激活所有组合键
//		 */		
//		public function activateAllKeyCombo():void
//		{
//			for each(var keyCombo:KeyCombo in _keyCombos)
//			{
//				keyCombo.isAction=true;
//			}
//		}
		
		/**
		 *激活指定的组合键 
		 * @param type 类型名称
		 */
		public function activateKeyCombo(type:String):void
		{
			var keyCombo:KeyCombo=getKeyCombo(type);
			if(keyCombo)keyCombo.isAction=true;
		}
		
		/**
		 *取消激活指定的组合键内单位键
		 */		
		public function deactivateKeyComboCell(type:String, name:String):void
		{
			var keyCombo:KeyCombo=getKeyCombo(type);
			if(keyCombo)
			{
				var keyComboCell:KeyComboCell=keyCombo.getKeyComboByName(name);
				if(keyComboCell)keyComboCell.isAction=false;	
			}
		}
		
		/**
		 *激活指定的组合键 
		 * @param type 类型名称
		 */
		public function activateKeyComboCell(type:String, name:String):void
		{
			var keyCombo:KeyCombo=getKeyCombo(type);
			if(keyCombo)
			{
				var keyComboCell:KeyComboCell=keyCombo.getKeyComboByName(name);
				if(keyComboCell)keyComboCell.isAction=true;
			}
		}
	}
}